﻿#region

using System;
using System.Windows.Forms;
using Ink_Master.Bots.InkMaster.Actions;
using Ink_Master.Bots.InkMaster.InfoBuilders;
using Ink_Master.Bots.InkMaster.Objects;
using NewMixedMode;
using Styx;
using Styx.Helpers;
using Styx.Logic.BehaviorTree;
using TreeSharp;
using Action = TreeSharp.Action;

#endregion

namespace Ink_Master.Bots.InkMaster
{
    public class InkMaster : BotBase
    {
        public static bool ChangingPrimaryBot;
        public static InkCollector.InkCollectionInfo InkCollection;
        public static bool IsRunning;
        public static string NearestHerb;
        public static uint NearestContinentOfHerb;
        private readonly Version _version = new Version(0, 0, 1);
        private Composite _root;

        public override string Name
        {
            get { return "Ink Master[v" + _version + "]"; }
        }

        public override Form ConfigurationForm
        {
            get { return new Config(); }
        }

        public override PulseFlags PulseFlags
        {
            get { return PulseFlags.All; }
        }

        public override bool IsPrimaryType
        {
            get { return false; }
        }

        /// <summary>
        ///   Gets a value indicating whether the requirements met for this bot to be run. Secondary type bots MUST implement this
        ///   member, for the bot to be used when needed.
        /// </summary>
        /// <value>
        ///   true if requirements met, false if not.
        /// </value>
        public override bool RequirementsMet
        {
            get
            {
                Log.Slog("Pulse Check");
                // If anything is wrong with our char lets give control back to the primary bot, they can deal with it
                // no point in duplicating code.
                if (StyxWoW.Me == null || !StyxWoW.IsInGame || !StyxWoW.IsInWorld || StyxWoW.Me.IsFalling ||
                    StyxWoW.Me.Dead || StyxWoW.Me.IsGhost || StyxWoW.Me.Combat)
                {
                    return false;
                }
                if (ChangingPrimaryBot)
                {
                    ChangingPrimaryBot = false;
                    return true;
                }
                // Check are we done?
                if (CheckStatus.AreWeDone(InkCollection, false))
                {
                    Log.Slog("We've gathered " + InkCollection.InkQty + " x " + InkCollection.Ink);
                    MixedModeEx.Instance.PrimaryBot.Stop();
                    TreeRoot.Stop();
                }
                //  Can we mill herbs?
                if (CheckStatus.HerbsToMIll())
                {
                    return true;
                }
                // Check can we turn pigment to ink?
                if (CheckStatus.PigmentsToChurn())
                {
                    return true;
                }

                // Are we running?
                if (!IsRunning)
                {
                    return true;
                }
                return false;
            }
        }


        public override Composite Root
        {
            get
            {
                return _root ?? (_root = new PrioritySelector(
                                             // Check if bot is in mixed mode, if yes thats fine if no, WOAAAAA hold your horses!                         
                                             new Decorator(ret => BotManager.Current.Name != "Mixed Mode",
                                                           new Sequence(
                                                               new Action(
                                                                   ret =>
                                                                   Log.Slog("Stopping HB. Please restart in Mixed Mode.")),
                                                               new Action(ret => TreeRoot.Stop()))),
                                             // Check the config form has been done.
                                             new Decorator(ret => string.IsNullOrEmpty(InkCollection.Ink),
                                                           new Sequence(
                                                               new Action(
                                                                   ret =>
                                                                   Log.Slog(
                                                                       "We don't appear to have anything to do, ensure you have completed the config form and try again.")),
                                                               new Action(ret => TreeRoot.Stop()))),
                                             // Can we mill herbs?
                                             new Decorator(ret => CheckStatus.HerbsToMIll(),
                                                           new Sequence(
                                                               new Action(ret => Log.Slog("STARTING TO MILL HERBS")),
                                                               MountHelpers.LandAndDismount(),
                                                               new Action(ret => Herbs.HerbsToPigments()),
                                                               new Action(ret => Log.Slog("Finished Milling Herbs")))),
                                             // Check can we turn pigment to ink?
                                             new Decorator(ret => CheckStatus.PigmentsToChurn(),
                                                           new Sequence(
                                                               new Action(ret => Log.Slog("Starting to Ink")),
                                                               MountHelpers.LandAndDismount(),
                                                               new Action(ret => Pigments.PigmentsToInk()),
                                                               new Action(ret => Log.Slog("Finished Inking")))),
                                             // Let's check we're not done
                                             new Decorator(ret => CheckStatus.AreWeDone(InkCollection, true),
                                                           new Sequence(
                                                               new Action(
                                                                   ret =>
                                                                   Log.Slog("We have gathered " + InkCollection.InkQty +
                                                                            " x " + InkCollection.Ink +
                                                                            ". Stopping Bot.")),
                                                               new Action(ret => TreeRoot.Stop()))),
                                             new Decorator(ret => !CheckStatus.AreWeDone(InkCollection, false),
                                                           new Sequence(
                                                               new Action(ret => Log.Slog("Ready to do stuff.")),
                                                               new Action(
                                                                   ret =>
                                                                   NearestHerb = HerbFinder.NereastHerb(InkCollection)),
                                                               new Action(
                                                                   ret =>
                                                                   NearestContinentOfHerb =
                                                                   HerbFinder.NearestContinentOfHerb(NearestHerb)),
                                                               new Action(
                                                                   ret =>
                                                                   Log.Slog("Nearest Herb To Us Is: " + NearestHerb +
                                                                            ". On map ID: " + NearestContinentOfHerb))))
                                                
                                             // TODO: Where should we be going, do we need to change continent etc?
                                             ));
            }
        }

        public override void Pulse()
        {
        }

        public override void Start()
        {
            StyxSettings.Instance.LogoutForInactivity = false;
            // TODO Remove Hack
            InkCollection = Construct.ConstructInkCollectorItem("Ivory Ink", 5);
        }

        public override void Stop()
        {
            StyxSettings.Instance.LogoutForInactivity = true;
        }
    }
}